
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import '@/style/common.scss'
import store from '@/store'
import { renderWithQiankun, qiankunWindow } from 'vite-plugin-qiankun/dist/helper'

// 使用乾坤渲染子应用
renderWithQiankun({
  // 挂载时
  mount (props) {
    console.log('mount')
    render(props)
  },
  bootstrap () {
    console.log('bootstrap')
  },
  unmount (props) {
    console.log('unmount', props)
  },
})

// 如果不是乾坤加载的此项目，则正常走以前的渲染过程
if (!qiankunWindow.__POWERED_BY_QIANKUN__) {
  render({})
}

function render (props = {}) {
  // 如果是乾坤来加载，会有主项目的容器标签，如果子项目自己启动 container 值为 undefined
  const { container } = props
  const app = createApp(App)
  app.use(router)
  app.use(store)
  app.mount(container ? container.querySelector("#app") : "#app")
}

// 回顾知识点：
/********************************************************* */
// 一. 构造函数（面向对象的编程思想）
// 面向过程：把每一步的实现从上到下逐一进行实现

// 面向过程创建一个人
// function createPeople(){
//   const per = {}
//   per.name = '张三'
//   per.age = 18
//   per.gender = '男'
//   per.hobby = ['篮球','足球']
//   console.log(per.name)
// }

// 面向过程创建一个 DOM 标签
// function createCube(){
//   const cube = document.createElement('div')
//   cube.style.width = '100px'
//   cube.style.height = '100px'
//   cube.style.backgroundColor = 'red'
//   document.body.appendChild(cube)
// }
// createCube()

// // 面向对象（先准备类模板），用模板批量实例化创建正方形对象（你需要什么，调用正方形对象的属性和方法）
// // 1. 准备一个类模板（类）
// function Cube(width, height, color) {
//   // 2. 共有特征=>属性
//   this.width = width
//   this.height = height
//   this.color = color
//   this.tag = document.createElement('div')
// }
// // 3. 在原型上添加方法和逻辑
// // 节省内存（所有实例对象共用同一个方法）
// Cube.prototype.draw = function () {
//   this.tag.style.width = this.width + 'px'
//   this.tag.style.height = this.height + 'px'
//   this.tag.style.backgroundColor = this.color
//   document.querySelector('#app').appendChild(this.tag)
// }

// // 4. 实例化具体的对象
// // new 的作用：
// // new 每次调用时创建一个新的空白对象，到构造函数里替换 this 的值
// // 往这个空白对象上增加属性和方法，默认返回到 new 调用的位置
// // 引用类型比较的都是内存地址（对象/数组/函数）
// const theCube = new Cube(100, 100, 'red')
// const theCube2 = new Cube(22, 22, 'yellow')
// // console.log(theCube.draw === theCube2.draw) // true
// theCube.draw()
// theCube2.draw()
// console.log(theCube,theCube2)
// /********************************************************* */
// // 二. 设计模式 - 订阅发布模式
// // 需求1：让第一个正方形-不断的变换颜色
// // 需求2：让第二个正方形-宽度不断变换
// // 1. 单例模式
// function Manager() {
//   // 2. 准备一个容器
//   // map: 的 key 可以用标签来代表
//   // map 对象和普通对象的区别：
//   // map 的 key 可以是任意类型（标签对象/数字等等）
//   // 普通 JS 对象的 key 只能是字符串类型
//   this.list = new Map()
//   // key: value
//   // 标签：回调函数
// }
// Manager.getInstance = function() {
//   if (!Manager.instance) {
//     Manager.instance = new Manager()
//   }
//   return Manager.instance
// }
// // 3. 准备订阅用的方法
// Manager.prototype.subscribe = function(tag, fn) {
//   this.list.set(tag, fn)
// }
// // 4. 准备发布用的方法
// Manager.prototype.publish = function() {
//   this.list.forEach((fn) => {
//     // fn 就是 subscribe 里的回调函数
//     fn()
//   })
// }

// // 给第一个正方形订阅
// Manager.getInstance().subscribe(theCube, () => {
//   const color = `rgb(${Math.floor(Math.random() * 256)}, ${Math.floor(Math.random() * 256)}, ${Math.floor(Math.random() * 256)})`
//   theCube.tag.style.backgroundColor = color
// })
// // 给第二个正方形订阅
// Manager.getInstance().subscribe(theCube2, () => {
//   const theW = Math.floor(Math.random() * 200)
//   theCube2.tag.style.width = theW + 'px'
// })

// setInterval(() => {
//   Manager.getInstance().publish()
// }, 1000)


// /********************************************************* */
// // 三. 设计模式 - 单例模式
// // 单例模式：无论调用多少次构造函数，始终返回相同的一个实例对象
// // 场景：封装工具类
// // 语法：
// function MouseHandler() {
//   this.tagList = []
// }
// // 单例模式一般创造实例的函数都是类函数，直接绑定在类（构造函数）身上
// MouseHandler.getInstance = () => {
//   // 如果类对象身上没有 instance 属性的值（第一次调用 getInstance）
//   if (!MouseHandler.instance) {
//     // 创建一个实例对象
//     MouseHandler.instance = new MouseHandler()
//   }

//   return MouseHandler.instance
// }

// const obj1 = MouseHandler.getInstance()
// const obj2 = MouseHandler.getInstance()
// const obj3 = MouseHandler.getInstance()
// console.log(obj1 === obj2)
// console.log(obj2 === obj3)
// // 问题：为什么要保证每次调用都是同一个实例对象？
// // 答案：单例模式为了保证你只有一个实例对象，所有数据都挂载添加到同一个对象的属性下，统一调度管理使用


// /*************************************************************** */
// // 四. Promise 语法
// // 概念：ES6 中新增的一个构造函数，用于管理异步任务
// // 场景：使用 axios 函数的时候，得到一个 Promise 对象（内部有 AJAX 的异步任务），使用 Promise 对象提供的 then 函数，catch 函数接收 / async+await 提取成功的结果，try + catch 捕获失败的结果
// // 解决：回调地狱的问题，把异步回调流程变为 await 等待同步流程代码阅读~读起来结构更清晰~
// // 语法：
// const p1 = new Promise((resolve) => {
//   // 异步代码
//   console.log(1)
//   setTimeout(() => {
//     resolve('成功的结果1')
//   }, 1000)
// })
// p1.then((res) => {
//   console.log(res)
// })

// // Promise.all() 
// // 概念：把多个 Promise 对象内异步任务等待同时全都成功后，一起收集返回结果
// // 返回值：Promise 对象
// const p2 = new Promise((resolve) => {
//   // 异步代码
//   console.log(1)
//   setTimeout(() => {
//     resolve('成功的结果2')
//   }, 3000)
// })
// const p3 = new Promise((resolve) => {
//   // 异步代码
//   console.log(1)
//   setTimeout(() => {
//     resolve('成功的结果3')
//   }, 5000)
// })
// // 场景：想要等待多个 Promise 对象都成功后再一起把成功结果拿到
// // allList：就是所有小 Promise 对象兑现的结果（顺序跟你传入 Promise.all 形参里数组的顺序一致）
// Promise.all([p1, p2, p3]).then(allList => {
//   console.log(allList)
// })

